#!/usr/bin/env python
# -*- coding: utf-8 -*-
# title       :
# author      : jarry

import sys
import os
import logging
from SceneCheckTool.checkScript.CheckBase import CheckBase

try:
    import maya.cmds as cmds
    import pymel.core as pm
    import jarryLibs.mayakit.MayaUtils as mu
    reload(mu)
except:
    pass

logging.basicConfig()
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)


class ELSAssetArnoldSet(CheckBase):
    def __init__(self):
        super(ELSAssetArnoldSet, self).__init__()
        pass

    def init_file(self):
        import elsLibs.AssetInfoFromFile as elsaif
        reload(elsaif)
        current_file = cmds.file(query=True, sn=True)
        aif = elsaif.AssetInfoFromFile(current_file)
        self.asset_name = aif.get_name
        self.shortType = aif.get_shortType
        self.step = aif.get_step
        self.asset_root_set_name = self.shortType + '_' + self.asset_name

    def create_set(self, name):
        deafault_sets = ['defaultLightSet', 'defaultObjectSet', 'lightEditorRoot']
        set_list = [s for s in pm.ls(type='objectSet') if s.type() == 'objectSet' and s.name() not in deafault_sets]
        for s in set_list:
            if name == s.name():
                return s
        set_node = pm.sets()
        set_node.rename(name)
        set_node.clear()
        return set_node

    def add_attr(self, node, attr_name, type, dv, en=''):
        node = pm.PyNode(node)
        if not node.hasAttr(attr_name):
            if type == 'string':
                node.addAttr(attr_name, dt=type)
                node.setAttr(attr_name, dv, type='string')
            else:
                node.addAttr(attr_name, at=type, en=en, dv=dv)

    def doit(self):
        root_set_name = '%s_ar_set' % self.asset_root_set_name
        root_set_node = self.create_set(root_set_name)
        self.add_attr(root_set_node, 'aiMatte', 'bool', 0)
        self.add_attr(root_set_node, 'primaryVisibility', 'bool', 1)
        self.add_attr(root_set_node, 'aiSelfShadows', 'bool', 1)
        # self.add_attr(root_set_name, 'aiSubdivType', 'enum', 1, 'none:catclark:linear')
        # self.add_attr(root_set_name, 'aiSubdivIterations', 'byte', 1)

        ar_subd0_set_name = '%s_ar_subd0_set' % self.asset_name
        ar_subd0_set_node = self.create_set(ar_subd0_set_name)
        root_set_node.add(ar_subd0_set_node)

        ar_subd1_set_name = '%s_ar_subd2_set' % self.asset_name
        ar_subd1_set_node = self.create_set(ar_subd1_set_name)
        self.add_attr(ar_subd1_set_node, 'aiSubdivType', 'enum', 1, 'none:catclark:linear')
        self.add_attr(ar_subd1_set_node, 'aiSubdivIterations', 'byte', 2)
        root_set_node.add(ar_subd1_set_node)

        ar_op_set_name = '%s_ar_op_set' % self.asset_name
        ar_op_set_node = self.create_set(ar_op_set_name)
        self.add_attr(ar_op_set_name, 'aiOpaque', 'bool', 0)
        self.add_attr(ar_op_set_name, 'aiVisibleInDiffuseReflection', 'bool', 1)
        root_set_node.add(ar_op_set_node)

        ar_sssnm_set_name = '%s_ar_sssname_set' % self.asset_name
        ar_sssnm_set_node = self.create_set(ar_sssnm_set_name)
        self.add_attr(ar_sssnm_set_node, 'aiSssSetname', 'string', '%s_sssname' % self.asset_name)
        root_set_node.add(ar_sssnm_set_node)

    def get_top_set(self, set):
        connection_name = set + ".message"
        if cmds.listConnections(set, connections=1):
            if connection_name in cmds.listConnections(set, connections=1):
                if cmds.connectionInfo(connection_name, dfs=True):
                    set_parent = cmds.connectionInfo(connection_name, dfs=True)[0].split(".")[0]
                    return self.get_top_set(set_parent)
        return set

    def is_parent(self, group_node, check_node):
        if cmds.listRelatives(check_node, parent=1):
            parent_node = cmds.listRelatives(check_node, parent=1)[0]
            if parent_node == group_node:
                return True
            if cmds.listRelatives(parent_node, parent=1):
                return self.is_parent(group_node, parent_node)
            return False
        else:
            return False

    def mesh_set_check(self):
        root_set_name = '%s_ar_set' % self.asset_root_set_name
        miss_set_nodes = []
        render_mod = '%s_%s_render_grp' % (self.shortType, self.asset_name)
        for mesh in cmds.ls(type="mesh"):
            if not self.is_parent(render_mod, mesh):
                continue
            msh_node = cmds.listRelatives(mesh, parent=1)[0]
            connection_name = msh_node + ".instObjGroups"
            if cmds.listConnections(msh_node, connections=1):
                if connection_name in cmds.listConnections(msh_node, connections=1):
                    for i in cmds.connectionInfo(connection_name, dfs=True):
                        set_name = i.split(".")[0]
                        set_top_group = self.get_top_set(set_name)
                        if set_top_group != root_set_name:
                            miss_set_nodes.append(msh_node)
                else:
                    miss_set_nodes.append(msh_node)
            else:
                miss_set_nodes.append(msh_node)
        return miss_set_nodes


    def check(self):
        current_file = cmds.file(query=True, sn=True)
        if not current_file:
            result_log = u'Error: 当前文件未保存!'
            return result_log
        try:
            self.init_file()
        except:
            result_log = u'Error:当前文件不符合ELS项目资产文件命名规则'
            return result_log
        root_set_name = '%s_ar_set' % self.asset_root_set_name

        if not pm.objExists(root_set_name):
            result_log = u'Error:不存在这个资产对应的ArSet: %s\n' % root_set_name
            return result_log
        else:
            result_log = u'Succeed:没有问题\n'

        miss_set_meshes = self.mesh_set_check()
        if miss_set_meshes:
            result_log = u'Error:以下模型未匹配对应的ArSet: %s\n' % miss_set_meshes
        else:
            result_log = u'Succeed:没有问题\n'
        return result_log

    def fix(self):
        current_file = cmds.file(query=True, sn=True)
        if not current_file:
            result_log = u'Error: 当前文件未保存!'
            return result_log
        try:
            self.init_file()
        except:
            result_log = u'Error:当前文件不符合ELS项目资产文件命名规则'
            return result_log

        root_set_name = '%s_ar_set' % self.asset_root_set_name

        if not pm.objExists(root_set_name):
            try:
                self.doit()
                result_log = u'Succeed:%s创建成功\n' % root_set_name
                return result_log
            except:
                return u'Error:%s创建失败\n' % root_set_name

        else:
            return u'Succeed:没有问题'

